/*
  Copyright (c) 2010 Les Newell. All rights reserved

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef ARRAY_H_INCLUDED
#define ARRAY_H_INCLUDED

#define GROWAHEAD 5

template <class T>
class GrowArray
{

public:
    GrowArray()
    {
        m_count=0;
        m_size = 0;
        m_data = NULL;
    };

    ~GrowArray()
    {
        Clear();
    };


    void Add(const T& data)
    {
        if (m_count >= m_size)
            Grow(GROWAHEAD);
        m_data[m_count] = data;
        m_count ++;
    };


    int Index(const T& data)
    {
        for (int ct=0; ct < m_count; ct++)
        {
            if (data == m_data[ct])
                return(ct);
        }
        return(-1);
    }

    inline T& operator[](const int index) const
    {
        return(m_data[index]);
    };

    void Swap(const int i1,const int i2)
    {
        if ((unsigned int)i1 >= (unsigned int)m_count)
            return;
        if ((unsigned int)i2 >= (unsigned int)m_count)
            return;
        T tmp = m_data[i1];
        m_data[i1] = m_data[i2];
        m_data[i2] = tmp;
    }

    void Remove(const int index)
    {
        if ((unsigned int)index >= (unsigned int)m_count)
            return;
        for (int ct=index; ct<m_count -1; ct++)
            m_data[ct] = m_data[ct+1];
        m_count --;
    };

    void Clear(void)
    {
        m_count=0;
        free(m_data);
        m_size=0;
        m_data = NULL;
    };

    void Empty(void)
    {
        m_count=0;
    };

    void Grow(size_t amount)
    {
        m_size += amount;
        m_data = (T*) realloc (m_data, sizeof(T) * m_size);
    }

    inline int GetCount(void) const
    {
        return(m_count);
    }

    T* m_data; //slighty ugly to expose this but it is faster


protected:
    int m_size;
    int m_count;
};



#endif

